﻿using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.U2D;

public sealed class CommonUtility {

    public static Transform InstantiateFrom(string path, Transform parent) {
        var t = Object.Instantiate(LoadPrefab(path)).transform;
        var pos = t.localPosition;
        var rot = t.localEulerAngles;
        var scale = t.localScale;
        t.SetParent(parent);
        t.localPosition = pos;
        t.localEulerAngles = rot;
        t.localScale = scale;
        return t;
    }

    public static PlayableAsset LoadTimeline(string path) {
        var res = ResourceManager.Instance.GetResource(path, typeof(PlayableAsset), enResourceType.ScenePrefab);

        if (res.m_content) {
            return res.m_content as PlayableAsset;
        }

        return null;
    }

    public static GameObject LoadPrefab(string path) {
        var res = ResourceManager.Instance.GetResource(path, typeof(GameObject), enResourceType.ScenePrefab);

        if (res.m_content) {
            return res.m_content as GameObject;
        }

        return null;
    }

    public static Object LoadObject(string path) {
        var res = ResourceManager.Instance.GetResource(path, typeof(Object), enResourceType.Prefab);

        if (res.m_content) {
            return res.m_content as Object;
        }

        return null;
    }

    public static Texture2D LoadTexture(string path) {
        var res = ResourceManager.Instance.GetResource(path, typeof(Texture2D), enResourceType.Prefab);

        if (res.m_content) {
            return res.m_content as Texture2D;
        }

        return null;
    }

    public static Sprite GetCakeSprite(string name) {
        return GetSprite(emUIAltas.CakeAtlas, name);
    }

    public static Sprite GetAdditionSprite(string name) {
        return GetSprite(emUIAltas.AdditionAtlas, name);
    }

    public static Sprite GetChineseRestaurantSprite(string name) {
        return GetSprite(emUIAltas.ChineseRestaurantAtlas, name);
    }

    public static Sprite GetCommonSprite(string name) {
        return GetSprite(emUIAltas.CommonAtlas, name);
    }

    public static Sprite GetSprite(emUIAltas atlas, string name) {
        var sprite = UISpriteManager.Instance.GetSprite(atlas, name);

        if (sprite) {
            return sprite;
        } else {
            UISpriteManager.Instance.LoadAtlas(atlas);
            return GetSprite(atlas, name);
        }
    }

    /// <summary>
    /// 判断顺时针逆时针：顺正逆负
    /// </summary>
    /// <param name="current">当前坐标</param>
    /// <param name="last">上个坐标</param>
    /// <param name="anchor">锚点</param>
    /// <returns></returns>
    public static bool IsClockwise(Vector2 current, ref Vector2 last, Vector2 anchor) {
        Vector2 lastDir = (last - anchor).normalized;    
        Vector2 currentDir = (current - anchor).normalized;

        float lastDot = Vector2.Dot(Vector2.right, lastDir);
        float currentDot = Vector2.Dot(Vector2.right, currentDir);

        float lastAngle = last.y < anchor.y ? Mathf.Acos(lastDot) * Mathf.Rad2Deg : -Mathf.Acos(lastDot) * Mathf.Rad2Deg;
        float currentAngle = current.y < anchor.y ? Mathf.Acos(currentDot) * Mathf.Rad2Deg : -Mathf.Acos(currentDot) * Mathf.Rad2Deg;

        last = current;
        return (currentAngle - lastAngle) > 0f;
    }

    public static bool IsClockwise(Vector2 current, ref Vector2 last) {
        var anchor = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f);
        return IsClockwise(current, ref last, anchor);
    }

    public static Dictionary<string, Dictionary<string, string>> LoadCsvFile(string filePath) {
        var result = new Dictionary<string, Dictionary<string, string>>();
        string[] fileData = File.ReadAllLines(filePath);

        // CSV文件的第一行为Key字段，第二行开始是数据。第一个字段一定是ID
        string[] keys = fileData[0].Split(',');

        for (int i = 1; i < fileData.Length; i++) {
            string[] line = fileData[i].Split(',');

            // 以ID为key值，创建一个新的集合，用于保存当前行的数据
            string id = line[0];
            result[id] = new Dictionary<string, string>();

            for (int j = 0; j < line.Length; j++) {
                // 每一行的数据存储规则：Key字段-Value值
                result[id][keys[j]] = line[j];
            }
        }

        return result;
    }

    public static Dictionary<int, T_CsvData> LoadCsvData<T_CsvData>(string csvFilePath) {
        var dict = new Dictionary<int, T_CsvData>();
        Dictionary<string, Dictionary<string, string>> result = LoadCsvFile(csvFilePath);

        // 遍历每一行数据
        foreach (string id in result.Keys) {
            // CSV的一行数据
            Dictionary<string, string> datas = result[id];

            // 读取Csv数据对象的属性
            PropertyInfo[] props = typeof(T_CsvData).GetProperties();

            // 使用反射，将CSV文件的数据赋值给CSV数据对象的相应字段，要求CSV文件的字段名和CSV数据对象的字段名完全相同
            T_CsvData obj = System.Activator.CreateInstance<T_CsvData>();

            foreach (PropertyInfo pi in props) {
                pi.SetValue(obj, System.Convert.ChangeType(datas[pi.Name], pi.PropertyType), null);
            }

            // 按ID-数据的形式存储
            dict[System.Convert.ToInt32(id)] = obj;
        }

        return dict;
    }
}
